package com.wjc.train.business.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.wjc.train.business.entity.ConfirmOrder;
import com.wjc.train.business.entity.DailyTrainSeat;
import com.wjc.train.business.entity.DailyTrainTicket;
import com.wjc.train.business.entity.OrderTickets;
import com.wjc.train.business.enums.ConfirmOrderStatusEnum;
import com.wjc.train.business.feign.MemberFeign;
import com.wjc.train.business.repository.ConfirmOrderRepository;
import com.wjc.train.business.repository.DailyTrainCarriageRepository;
import com.wjc.train.business.repository.DailyTrainSeatRepository;
import com.wjc.train.business.repository.DailyTrainTicketRepository;
import com.wjc.train.common.req.MemberTicketSaveReq;
import com.wjc.train.common.untils.CopyUtil;
import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 确认订单表 服务实现类(事务)
 * </p>
 *
 * @author Guessed
 * @since 2023-08-15
 */
@Service
@Slf4j
public class AfterConfirmOrderServiceImpl  {

    @Resource
    private ConfirmOrderRepository confirmorderRepository;

    @Resource
    private DailyTrainTicketRepository dailytrainticketRepository;

    @Resource
    private DailyTrainSeatServiceImpl dailyTrainSeatService;

    @Resource
    private MemberFeign memberFeign;

    @Resource
    private DailyTrainCarriageRepository dailytraincarriageRepository;

    @Resource
    private DailyTrainSeatRepository dailyTrainSeatRepository;

    /**
     *  选中座位后进行事务处理
     *   座位表修改售卖情况sell
     *     修改余票数量
     *        为会员增加购票记录
     *        更新订单信息状态
     */
//    @Transactional(rollbackFor = Exception.class)
    @GlobalTransactional
    public void afterDoConfirm(DailyTrainTicket trainTicket,
                               List<DailyTrainSeat> finalSeatList,
                               List<OrderTickets> orderTickets,
                               ConfirmOrder orderCopy){
        log.info("seata全局事务ID:{}", RootContext.getXID());

       //座位表修改售卖情况sell
        dailyTrainSeatRepository.saveOrUpdateBatch(finalSeatList);
        List<MemberTicketSaveReq> memberTicketSaveReqList = new ArrayList<>();
        // 修改余票数量
        for (int j = 0; j < finalSeatList.size(); j++) {
            DailyTrainSeat finalSeat = finalSeatList.get(j);
            OrderTickets ticket = orderTickets.get(j);
            // 计算这个站卖出去后,影响了哪些站的库存
            // 影响的库存: 本次选座之前没卖过票的，和本次购买的区间有交集的区间
            // 假设10个站，本次买4~7站
            // 原售:001000001
            // 购买:000011100
            // 新售:001011101
            // 影响: XXX11111X
            //最小区间应该为新售中查找从本次购买的起始区间往前找到最近的一个1,1后面的0就是最小区间的起始点
            //例: 001011101 -> [111]为本次购买的站,则往前找到[0010]中最后一个0
//            Integer minStartIndex = startIndex - 1; //往前碰到的最后一个0
//            Integer maxStartIndex = endIndex - 1;
//            Integer minEndIndex = startIndex + 1;
//            Integer maxEndIndex = endIndex + 1; //往后碰到的最后一个0
            Integer startIndex = Integer.valueOf(trainTicket.getStartIndex());
            Integer endIndex = Integer.valueOf(trainTicket.getEndIndex());
            Integer maxStartIndex = endIndex - 1;
            Integer minEndIndex = startIndex + 1;
            Integer minStartIndex = 0;
            char[] chars = finalSeat.getSell().toCharArray();
            for (int i = startIndex - 1; i >= 0; i--) {
                char aChar = chars[i];
                if (aChar == '1') {
                    minStartIndex = i + 1;
                    break;
                }
            }
            log.info("影响的出发站区间：" + minStartIndex + "-" + maxStartIndex);
            Integer maxEndIndex = finalSeat.getSell().length();
            for (int i = endIndex; i < finalSeat.getSell().length(); i++) {
                char aChar = chars[i];
                if (aChar == '1') {
                    maxEndIndex = i;
                    break;
                }
            }
            log.info("影响的到达站区间："+minEndIndex + "-" + maxEndIndex);
            dailytrainticketRepository.getBaseMapper().updateCountBySell(finalSeat.getTrainDate(),
                                                                    finalSeat.getTrainCode(),
                                                                    finalSeat.getSeatType(),
                                                                    minStartIndex,
                                                                    maxStartIndex,
                                                                    minEndIndex,
                                                                    maxEndIndex);
            memberTicketSaveReqList.add(buildTicket(finalSeat,trainTicket,ticket,orderCopy.getMemberId()));
            
        }
        if(CollectionUtil.isNotEmpty(memberTicketSaveReqList)){
            //为会员增加购票记录
            memberFeign.saveList(memberTicketSaveReqList);
            //更新订单状态
            orderCopy.setStatus(ConfirmOrderStatusEnum.SUCCESS.getCode());
            confirmorderRepository.saveOrUpdate(orderCopy);
        }

    }

    private MemberTicketSaveReq buildTicket(DailyTrainSeat finalSeat,
                                            DailyTrainTicket trainTicket,
                                            OrderTickets ticket,
                                            Long memberId){
        MemberTicketSaveReq copy = CopyUtil.copy(finalSeat, MemberTicketSaveReq.class);
        copy.setId(null);
        copy.setMemberId(memberId);
        copy.setPassengerId(Long.valueOf(ticket.getPassengerId()));
        copy.setPassengerName(ticket.getPassengerName());
        copy.setTrainDate(trainTicket.getDate());
        copy.setStartStation(trainTicket.getStart());
        copy.setStartTime(trainTicket.getStartTime());
        copy.setEndStation(trainTicket.getEnd());
        copy.setEndTime(trainTicket.getEndTime());
        return copy;
    }
}
